package com.partvoyage.server.servlet;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.oauth.OAuthRequestException;
import com.google.appengine.api.oauth.OAuthService;
import com.google.appengine.api.oauth.OAuthServiceFactory;
import com.google.gdata.client.authn.oauth.GoogleOAuthHelper;
import com.google.gdata.client.authn.oauth.GoogleOAuthParameters;
import com.google.gdata.client.authn.oauth.OAuthHmacSha1Signer;
import com.partvoyage.server.utils.Configuration;
import com.partvoyage.server.utils.ServletUtils;
import com.partvoyage.shared.model.AccessToken;

public class OAuthAccessServlet extends HttpServlet {
	private final static Logger log = Logger.getLogger(OAuthAccessServlet.class
			.getName());

	@Override
	protected void service(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		this.setGrantedAccessTokenToSession(request);
		this.setCurrentUtilisateurToSession(request);
		response.sendRedirect(Configuration.getHomeUrl());

		log.info("service():: exit");
	}

	private void setGrantedAccessTokenToSession(HttpServletRequest request)
			throws IOException {
		log.info("service():: start");

		String requestContent = ServletUtils.toString(request.getInputStream());
		log.info("service():: request=" + requestContent);

		try {
			String appScope = request.getParameter("appScope");

			AccessToken grantAccessToken = ServletUtils
					.getAccessTokenFromSession(appScope, request.getSession());

			if (grantAccessToken == null) {
				throw new IllegalStateException(
						"Le token retourner est null pour le scope "
								+ appScope
								+ ", il faut regarder les configurations peut etre qu'elles sont fausses (voir la racine de l'url utilisée");
			}
			log.info("service():: original accessToken=" + grantAccessToken != null ? grantAccessToken
					.toString() : "null");

			GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
			oauthParameters.setOAuthConsumerKey(Configuration
					.getConsumerToken());
			oauthParameters.setOAuthConsumerSecret(Configuration
					.getConsumerTokenSecret());
			oauthParameters.setOAuthTokenSecret(grantAccessToken
					.getOAuthTokenSecret());

			// retrieve access token
			GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(
					new OAuthHmacSha1Signer());
			oauthHelper.getOAuthParametersFromCallback(
					request.getQueryString(), oauthParameters);
			oauthHelper.getAccessToken(oauthParameters); // !!!

			String accessToken = oauthParameters.getOAuthToken();
			String accessTokenSecret = oauthParameters.getOAuthTokenSecret();

			grantAccessToken.setOAuthToken(accessToken);
			grantAccessToken.setOAuthTokenSecret(accessTokenSecret);

			ServletUtils.setAccessTokenToSession(appScope, grantAccessToken,
					request.getSession());

			log.info("service():: accessToken=" + grantAccessToken != null ? grantAccessToken
					.toString() : "null");
		} catch (Exception e) {
			log.log(Level.WARNING, "setGrantedAccessTokenToSession():: ", e);
		}
	}

	private void setCurrentUtilisateurToSession(HttpServletRequest request) {
		// On définit l'utilisateur courant
		try {
			OAuthService oauth = OAuthServiceFactory.getOAuthService();
			System.out.println("oauth.getOAuthConsumerKey() "
					+ oauth.getOAuthConsumerKey());
			System.out.println("oauth.getCurrentUser() "
					+ oauth.getCurrentUser());
			ServletUtils.setCurrentUserToSession(oauth.getCurrentUser(),
					request.getSession());
		} catch (OAuthRequestException e) {
			log.log(Level.WARNING, "setCurrentUtilisateurToSession():: ", e);
		}
	}
}
